<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .box{width: 300px;height: 40px;line-height: 40px;margin: 0 auto;text-indent: 4px;}
        .box span{display: block;width: 300px;height: 40px;border: solid 1px black;cursor: pointer;box-sizing: border-box}
        .box ul{margin: 0;padding: 0;list-style: none;border: solid 1px black;border-top:none;width: 300px;text-indent: 8px;display: none;;padding: 4px;box-sizing: border-box;}
        .box ul li.hover{background: #66f;color: #fff;}
    </style>
</head>
<body>
    <select name="" id="">
        <option value="北京">北京</option>
        <option value="上海">上海</option>
        <option value="广州">广州</option>
        <option value="深圳">深圳</option>
        <option value="杭州">杭州</option>
    </select>

    <div class="box">
        <span></span>
        <ul class="list">
            <li>北京</li>
            <li>上海</li>
            <li>广州</li>
            <li>深圳</li>
            <li>杭州</li>
        </ul>
    </div>
</body>
<script>
    var ospan = document.querySelector(".box span");
    var oul = document.querySelector(".list");
    var ali = oul.children;
    var flag=0;

    // 当前确认选中的索引
    var index = 0;

    // 键盘控制选项的索引
    var keyIndex;

    setDefault()
    for(var i=0;i<ali.length;i++){
        ali[i].xuhao = i;
        ali[i].onmouseover = function(){
            this.className = "hover";

            // 防止第一次鼠标进入选项，找不到keyIndex索引，而报错
            if(keyIndex !== undefined){
                ali[keyIndex].className = "";
            }
            
            // 鼠标进入选项时，将键盘的索引，设置为当前选项的索引
            keyIndex = this.xuhao;
            
            console.log(keyIndex);
        }
        ali[i].onmouseout = function(eve){
            var e = eve || window.event;
            stopBubble(e);

            this.className = "";
            // 鼠标离开选项时，将键盘的索引，设置为默认值
            // keyIndex = null;
        }
        ali[i].onclick = function(){
            ali[index].lastElementChild.remove();
            index = this.xuhao;
            setDefault()
            oul.style.display = "none";
            flag = 0;
        }
    }


    function setDefault(){
        ospan.innerHTML = ali[index].innerHTML;
        var em = document.createElement("em")
        em.innerHTML = "√";
        ali[index].appendChild(em);
    }

    ospan.onclick = function(eve){
        var e = eve || window.event;
        stopBubble(e);
        if(flag === 0){
            oul.style.display = "block";
            
            // 下拉菜单每次重新显示，都是需要将键盘所有内容设置为默认值
            if(keyIndex !== undefined){
                ali[keyIndex].className = "";
            }
            keyIndex = undefined;
            
            flag = 1;
        }else{
            oul.style.display = "none";
            flag = 0;
        }
    }


    document.onclick = function(){
        oul.style.display = "none";
        flag = 0;
    }


    function stopBubble(e){
        if(e.stopPropagation){
            e.stopPropagation()
        }else{
            e.cancelBubble = true;
        }
    }

    // ====================

    // 鼠标直接离开ul，将键盘的所有内容设置为默认值
    oul.onmouseout = function(){
        // console.log(keyIndex);
        if(keyIndex !== undefined){
            ali[keyIndex].className = "";
        }
        keyIndex = undefined;
    }
    

    document.onkeydown = function(eve){
        var e = eve || window.event;
        var code = e.keyCode || e.which;
        // 上
        if(code === 38){
            // 第一次按下键盘，需要将keyIndex设置为起点的上一个值
            if(keyIndex === undefined){
                keyIndex = ali.length;
            }
            // 计算索引
            if(keyIndex === 0){
                keyIndex = 0
            }else{
                keyIndex--;
            }
            // 如果索引为起点，不需要清除上一个元素的样式
            if(keyIndex !== ali.length-1){
                ali[keyIndex+1].className = "";
            }
            // 根据索引，添加样式
            ali[keyIndex].className = "hover";
        }
        // 下
        if(code === 40){
            if(keyIndex === undefined){
                keyIndex = -1;
            }
            if(keyIndex === ali.length-1){
                keyIndex = ali.length-1
            }else{
                keyIndex++;
            }
            if(keyIndex !== 0){
                ali[keyIndex-1].className = "";
            }
            ali[keyIndex].className = "hover"
        }
        // 回车
        if(code === 13){
            // 清除上一个选中的选项的选中状态
            ali[index].lastElementChild.remove();
            // 修改上一个选中的索引为键盘的索引
            index = keyIndex;
            // 设置选项的默认状态
            setDefault();
            // 隐藏下拉菜单
            oul.style.display = "none";
            // 修改下拉菜单显示状态
            flag = 0;
        }
    }






</script>
</html>